package mymyoux.io.sockets.servers
{
	import flash.events.ErrorEvent;
	import flash.utils.ByteArray;
	
	import mymyoux.debug.log;
	import mymyoux.io.sockets.clients.BinarySocket;
	import mymyoux.io.sockets.mapping.Telegramme;
	import mymyoux.io.sockets.servers.mserverClasses.People;
	import mymyoux.io.sockets.servers.mserverClasses.Peoples;
	import mymyoux.io.sockets.servers.mserverClasses.Room;
	import mymyoux.io.sockets.servers.mserverClasses.Rooms;
	import mymyoux.io.sockets.servers.mserverClasses.SBinarySocket;

	public class MServer
	{
		protected var serverSocket:BinaryServerSocket;
		protected var rooms:Rooms;
		protected var peoples:Peoples;
		public function MServer()
		{
			rooms = new Rooms();
			peoples = new Peoples();
			serverSocket = new BinaryServerSocket();
			serverSocket.signalStatus.add(onStatut);
			serverSocket.signalError.add(onError);
			
		}
		public function set host(value:String):void
		{
			serverSocket.host = value;
		}
		public function get host():String
		{
			return serverSocket.host;
		}
		public function connect():void
		{
			serverSocket.connect();
		}
		protected function onError(socket:BinarySocket, error:ErrorEvent):void
		{
			log("error[MServer]:"+socket);
		}
		protected function onSocketData(socket:BinarySocket, data:ByteArray, people:People):void
		{
			var t:Telegramme;
			var telegramme:Telegramme;
			while(data.bytesAvailable > 0)
			{
				trace("test");
				try
				{
					try
					{
						t = data.readObject();
					}catch(err:Error)
					{
						trace("rror");
					}
					trace("server receipt:"+t);
					switch(t.command)
					{
						case Telegramme.LOGIN:
							if(!people.logged)
							{
								telegramme = new Telegramme();
								telegramme.command = Telegramme.LOGIN;
								if(!peoples.contains(telegramme.id))
								{
									telegramme.action = Telegramme.LOGIN_OK;
									people.id = telegramme.id;
									peoples.add(people);
								}else
								{
									telegramme.action = Telegramme.LOGIN_ALREADY_CONNECTED;
								}
								socket.write(telegramme);
							}
						break;
						case Telegramme.GET_ROOM:
							
							var response:Telegramme = new Telegramme();
							response.action = Telegramme.ROOM_OK;
							response.command = Telegramme.GET_ROOM;
							response.room = t.room;
						//	telegramme.object = response;
							//socket.write(telegramme);
							socket.write(response);
						break;
						case Telegramme.SEND_ROOM:
							log("messageroom");
							socket.write(t);
						break;
						default:
							//TODO:default data
					}
				}catch(error:Error)
				{
					trace("pik");
					log("SERVER_ERROR_READING:["+error+"]");
					//if we are here, value is malformed
					break;
				}
			}
		}
		protected function onStatut(socket:BinarySocket, connected:Boolean):void
		{
			/*log("connect:"+socket);
			var people:People = new People();
			people.socket = socket;
			socket.signalData.add(onSocketData,people);*/
			var people:People = new People();
			people.socket = new SBinarySocket(socket);
			people.signalLog.addOnce(onPeopleLog, people);
			people.signalRoom.add(onPeopleRoom, people);
			people.signalDisconnect.addOnce(onPeopleDisconnect, people);
		}
		private function onPeopleDisconnect(people:People):void
		{
			var peopleRooms:Vector.<String> = people.rooms;
			var p:String;
			for(p in peopleRooms)
			{
				rooms.get(peopleRooms[p]).rem(people);
				if(rooms.get(peopleRooms[p]).empty)
				{	
					rooms.rem(rooms.get(peopleRooms[p]));
				}
			}
		}
		private function onPeopleRoom(roomName:String, comeIn:Boolean, people:People):void
		{
			var room:Room;
			//go into a room
			if(comeIn)
			{
				var telegramme:Telegramme = new Telegramme();
				telegramme.command = Telegramme.GET_ROOM;
				if(people.logged)
				{
					if(!rooms.contains(roomName))
					{
						room = new Room();
						room.name = roomName;
						rooms.add(room);
					}
					room = rooms.get(roomName);
					telegramme.value = room.peoplesId.toString();
					if(!room.contains(people))
					{
						room.add(people);
					}
					telegramme.action = Telegramme.ROOM_OK;
					telegramme.room = room.name;
				}else
				{
					//if user isn't logged yet
					telegramme.action = Telegramme.ROOM_FORBIDDEN;
				}
				people.socket.write(telegramme);
			}else
			{
				if(!rooms.contains(roomName))
				{
					room.rem(people);
					if(room.empty)
					{
						rooms.rem(room);
					}
				}
			}
		}
		protected function onPeopleLog(id:uint, people:People):void
		{
			var telegramme:Telegramme = new Telegramme();
			telegramme.command = Telegramme.LOGIN;
			if(!peoples.contains(id))
			{
				telegramme.action = Telegramme.LOGIN_OK;
				people.id = id;
				peoples.add(people);
			}else
			{
				telegramme.action = Telegramme.LOGIN_ALREADY_CONNECTED;
			}
			people.socket.write(telegramme);
		}
		public function set port(value:uint):void
		{
			serverSocket.port = value;
		}
		public function get port():uint
		{
			return serverSocket.port;
		}
	}
}